package com.admin.service.impl;

import com.admin.common.enums.*;
import com.admin.common.exception.BizException;
import com.admin.common.shiro.ShiroUtils;
import com.admin.common.util.DateUtils;
import com.admin.domain.*;
import com.admin.mapper.*;
import com.admin.req.declare.DeclareReq;
import com.admin.req.declare.DeclareUpgradeReq;
import com.admin.req.declarereturn.ReturnReq;
import com.admin.req.score.ScoreReq;
import com.admin.service.*;
import com.admin.vo.PageVO;
import com.admin.vo.ResultVO;
import com.admin.vo.declare.DeclareListVO;
import com.admin.vo.declareDetail.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author yangzhongliang
 * @date 2022/05/16
 */
@Slf4j
@Service
public class DeclareAreaServiceImpl implements DeclareAreaService {
    @Autowired
    private DeclareMapper declareMapper;
    @Autowired
    private AdminMapper adminMapper;
    @Autowired
    private DeclareService declareService;
    @Autowired
    private DeclareScoreService declareScoreService;
    @Autowired
    private DeclareLogService logService;
    @Autowired
    private DeclareReturnService declareReturnService;
    @Autowired
    private AdminService adminService;
    @Autowired
    private RegionMapper regionMapper;
    @Autowired
    private RegionsService regionsService;
    @Autowired
    private AttachmentService attachmentService;
    @Autowired
    private DeclareWeatherBureauMapper weatherBureauMapper;
    @Autowired
    private DeclareUpgradeMapper upgradeMapper;

    /**
     * 查询 自己 申报的记录
     * @param pageIndex
     * @param pageSize
     * @param params
     * @return
     */
    @Override
    public ResultVO<PageVO<DeclareListVO>> getPageList(Integer pageIndex, Integer pageSize, Map<String, Object> params) {
        ResultVO<PageVO<DeclareListVO>> result = new ResultVO<>();
        PageVO<DeclareListVO> page = new PageVO<>(pageIndex, pageSize);
        List<DeclareListVO> declareListVOList = new ArrayList<>();
        // 区县 用户 - 查询自己区县内的所有申报 记录
        Integer areaIds = adminService.getResponsibleAreaIds(ShiroUtils.getUserId());
        params.put("areaIds", Arrays.asList(areaIds));
        //提交上来的申报
        params.put("isSubmitArea", 1);

        Integer totalCount = declareMapper.countByMap(params);
        page.setTotalCount(totalCount);
        if (totalCount > 0) {
            // 查询管理员信息
            params.put("startIndex", page.getStartIndex());
            params.put("pageSize", page.getPageSize());
            List<Declare> declareList = declareMapper.selectByMap(params);
            if (!CollectionUtils.isEmpty(declareList)) {
                //查询所属街道
                List<Integer> countryIds = declareList.stream().map(e->e.getCountryId()).collect(Collectors.toList());
                List<Region> regionList = regionMapper.findByIds(countryIds);
                Map<Integer, Region> regionMap = regionList.stream().collect(Collectors.toMap(Region::getRegionId, Function.identity()));

                for (Declare declare : declareList) {
                    DeclareListVO itemVO = new DeclareListVO();
                    BeanUtils.copyProperties(declare, itemVO);

                    Region region = regionMap.get(declare.getCountryId());
                    if (!Objects.isNull(region)) {
                        itemVO.setCountryName(region.getRegionName());
                    }
                    itemVO.setDeclareStatusStr(DeclareStatusEnum.getText(declare.getDeclareStatus()));
                    itemVO.setScoreStatusStr(DeclareScoreStatusEnum.getText(declare.getScoreStatus()));
                    itemVO.setDeclareTypeStr(DeclareTypeEnum.getText(declare.getDeclareType()));
                    itemVO.setCreateTimeStr(DateUtils.format(declare.getCreateTime(), DateUtils.DATE_PATTERN_TIME));
                    declareListVOList.add(itemVO);
                }
            }
        }
        page.setData(declareListVOList);

        //申报用户数量 和 实际上报数量
        Map<String,Object> resultMap = new HashMap<>();
        resultMap.put("totalUserQuantity", adminService.totalUserQuantity(MemberLevelEnum.AREA.getKey(), areaIds));
        resultMap.put("submitUserQuantity", adminService.currentRoundDeclareQuantity(MemberLevelEnum.AREA.getKey(), areaIds));

        page.setMap(resultMap);
        result.setData(page);
        result.setCode(EnumResult.SUCCESS.getCode());
        result.setMsg(EnumResult.SUCCESS.getMsg());
        return result;
    }


    @Override
    public ResultVO saveScore(Integer userId, ScoreReq scoreReq) {
        //查询当前登录用户所属社区
        AdminDO adminDO = adminMapper.selectByPrimaryKey(userId);
        if (Objects.isNull(adminDO)) {
            throw new BizException(-1, "登录信息已失效,请重新登录!");
        }
        return declareScoreService.save(userId, scoreReq, MemberLevelEnum.AREA.getKey());
    }

    @Override
    public ResultVO areaReturn(Integer userId, ReturnReq req) {
        return declareReturnService.save(userId, req, MemberLevelEnum.AREA.getKey());
    }

    @Override
    public Boolean submitArea(Integer id) {
        Declare declare = declareMapper.selectByPrimaryKey(id);
        if (Objects.isNull(declare)) {
            throw new BizException(-1, "申报记录不存在或已删除!");
        }

        if (!declare.getScoreStatus().equals(DeclareScoreStatusEnum.AREA_SUCCESS.getKey())) {
            throw new BizException(-1, "区县未评分,暂不能提交上级!");
        }

        if (declare.getScoreStatus().equals(DeclareScoreStatusEnum.CITY_WAIT.getKey())) {
            throw new BizException(-1, "已提交上级,勿重复操作!");
        }

        Declare declareUpdate = new Declare();
        declareUpdate.setId(declare.getId());
        declareUpdate.setScoreStatus(DeclareScoreStatusEnum.CITY_WAIT.getKey());
        declareUpdate.setIsSubmitCity(1);
        declareMapper.updateByPrimaryKeySelective(declareUpdate);
        //记录日志
        //上级  区县 - 提交 市区
        DeclareLog declareLog = new DeclareLog();
        declareLog.setDeclareId(declare.getId());
        declareLog.setUserLevel(ShiroUtils.getMemberLevel());
        declareLog.setUserLevelName(ShiroUtils.getUserName());
        declareLog.setContent("提交申报至【"+regionsService.getById(declare.getCityId())+"】");
        declareLog.setOperatorType(DeclareLogTypeEnum.TYPE_22.getKey());
        logService.insertLog(declareLog);
        return true;
    }

    @Override
    public Boolean batchSubmitArea(String ids) {
        if (StringUtils.isEmpty(ids)) {
            throw new BizException(-1, "你还没有选择记录!");
        }
        String[] strIds = ids.split(",");
        for (String strId : strIds) {
            if (Objects.isNull(strId)) {
                continue;
            }
            try {
                submitArea(Integer.parseInt(strId));
            } catch (Exception e) {
                log.error("batchSubmitArea error , id:{}, error:{}", strId, e);
            }
        }
        return true;
    }

    /**
     * 详情  -  如果退回  有退回原因
     * @param id
     * @return
     */
    @Override
    public DeclareDetailVO detail(Integer id) {
        Declare declare = declareMapper.selectByPrimaryKey(id);
        if (Objects.isNull(declare)) {
            throw new BizException(-1, "申报记录不存在或已删除!");
        }

        //通用详情方法 -
        //新增别的数据
        DeclareDetailVO declareDetailVO = declareService.detail(id, MemberLevelEnum.AREA.getKey());

        return declareDetailVO;
    }



    @Transactional
    @Override
    public Boolean updateDeclareInfo(DeclareReq declareReq) {
        if (Objects.isNull(declareReq.getId()) || 0 == declareReq.getId()) {
            throw new BizException(-1, "参数id缺失!");
        }
        Declare declare = declareMapper.selectByPrimaryKey(declareReq.getId());
        if (Objects.isNull(declare)) {
            throw new BizException(-1, "申报记录不存在或已删除!");
        }
        //区县气象局评分
        if (Objects.nonNull(declareReq.getWeatherBureauReq())) {
            DeclareWeatherBureau weatherBureau = new DeclareWeatherBureau();
            BeanUtils.copyProperties(declareReq.getWeatherBureauReq(), weatherBureau);
            weatherBureau.setPrepareFiles(attachmentService.uploadAttachment(declare.getId(), declareReq.getWeatherBureauReq().getPrepareFiles()));
            weatherBureau.setDeclareId(declare.getId());
            DeclareWeatherBureau weatherBureauOld = weatherBureauMapper.getByDeclareId(declare.getId());
            if (!Objects.isNull(weatherBureauOld)) {
                weatherBureau.setId(weatherBureauOld.getId());
                weatherBureauMapper.updateByPrimaryKeySelective(weatherBureau);
            } else {
                weatherBureauMapper.insertSelective(weatherBureau);
            }
        }
        //提标升级
        if (Objects.nonNull(declareReq.getUpgradeReq())) {
            DeclareUpgradeReq upgradeReq = declareReq.getUpgradeReq();
            DeclareUpgrade upgrade = new DeclareUpgrade();
            upgrade.setDeclareId(declare.getId());
            //乡镇预警描述
            upgrade.setCountryWarningRemark(upgradeReq.getCountryWarningRemark());
            //落实证明描述
            upgrade.setCountryProveRemark(upgradeReq.getCountryProveRemark());
            //乡镇预警图片
            upgrade.setCountryWarningImages(attachmentService.uploadAttachment(declare.getId(), upgradeReq.getCountryWarningImages()));
            //分乡镇-服务机制-文件
            upgrade.setCountryServiceFiles(attachmentService.uploadAttachment(declare.getId(), upgradeReq.getCountryServiceFiles()));
            //落实到位证明材料
            upgrade.setCountryProveFiles(attachmentService.uploadAttachment(declare.getId(), upgradeReq.getCountryProveFiles()));
            //落实到位证明图片
            upgrade.setCountryProveImages(attachmentService.uploadAttachment(declare.getId(),upgradeReq.getCountryProveImages()));
            DeclareUpgrade upgradeOld = upgradeMapper.getByDeclareId(declare.getId());
            if (!Objects.isNull(upgradeOld)) {
                upgrade.setId(upgradeOld.getId());
                upgradeMapper.updateByPrimaryKeySelective(upgrade);
            } else {
                upgradeMapper.insertSelective(upgrade);
            }
        }
        return true;
    }
}
